package com.ccc.boot.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ccc.boot.base.BaseServiceImpl;
import com.ccc.boot.constant.AddrConstant;
import com.ccc.boot.constant.DictConstant;
import com.ccc.boot.exception.BusinessException;
import com.ccc.boot.pojo.AddrTree;
import com.ccc.boot.pojo.Query;
import com.ccc.boot.redis.constant.RedisConstant;
import com.ccc.boot.response.ResponseCode;
import com.ccc.boot.system.entity.SysAddr;
import com.ccc.boot.system.mapper.SysAddrMapper;
import com.ccc.boot.system.service.SysAddrService;
import com.ccc.boot.util.AddrUtils;
import com.ccc.boot.util.TreeUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 行政分区基本信息表 业务处理实现类
 *
 * @author superC
 * @version 0.1.0
 * @date 2022-04-14
 */
@Service
public class SysAddrServiceImpl extends BaseServiceImpl<SysAddrMapper, SysAddr> implements SysAddrService {

    @Override
    public IPage<SysAddr> page(Query query) {
        Page<SysAddr> page = new Page<>(query.getCurrent(), query.getSize());
        QueryWrapper<SysAddr> wrapper = new QueryWrapper<>();
        // 全局进行模糊查询
        query.forEach((column, value) -> {
            // 非空，进行模糊查询
            if (value != null && value != "") {
                wrapper.like(column, value);
            }
        });
        wrapper.orderByAsc("ad_cd");
        return super.page(page, wrapper);
    }

    @Override
    public SysAddr getByAdCd(String adCd) {
        LambdaQueryWrapper<SysAddr> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysAddr::getAdCd, adCd);
        SysAddr baseAddr = baseMapper.selectOne(wrapper);
        if (baseAddr == null) {
            throw new BusinessException(ResponseCode.RESULT_DATA_NONE);
        }
        return baseAddr;
    }

    /**
     * 获取所有有效数据
     *
     * @return java.util.List<com.kim.admin.domain.SysAddr>
     * @author superC
     * @date 2020/12/21 18:54
     */
    @Override
    public List<SysAddr> getAllList() {
        QueryWrapper<SysAddr> wrapper = new QueryWrapper<>();
        return getList(wrapper);
    }

    /**
     * 获取所有行政分区树形结构
     *
     * @return java.util.List<com.kim.common.dto.AddrTree>
     * @author superC
     * @date 2020/12/20 22:03
     */
    @Override
//    @Cacheable(value = RedisConstant.SYS_ADDR_TREE, key = "#adCd", unless = "#result == null")
    public List<AddrTree> getAddrTree(String adCd) {
        QueryWrapper<SysAddr> wrapper = new QueryWrapper<>();
        if (!Objects.equals(AddrConstant.COUNTRY_CD, adCd)) {
            String adCdLike = getAdCdLike(adCd);
            wrapper.lambda().like(SysAddr::getAdCd, adCdLike);
        }
        List<SysAddr> list = getList(wrapper);
        return this.getTree(list);
    }

    /**
     * 懒加载 获取一级行政分区树 【暂不使用】
     *
     * @return java.util.List<com.kim.common.dto.AddrTree>
     * @author superC
     * @date 2020/12/20 22:24
     */
    @Override
    public List<AddrTree> loadFirstAddrTree() {
        QueryWrapper<SysAddr> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(SysAddr::getPid, TreeUtils.ROOT_NODE);
        List<SysAddr> list = getList(wrapper);
        return this.transProperties(list, TreeUtils.ROOT_NODE);
    }

    /**
     * 获取子集行政分区树【暂不使用】
     *
     * @param id:
     * @return java.util.List<com.kim.common.dto.AddrTree>
     * @author superC
     * @date 2020/12/20 22:24
     */
    @Override
    public List<AddrTree> getSonAddrTree(Long id) {
        return null;
    }

    private List<SysAddr> getList(QueryWrapper<SysAddr> wrapper) {
        wrapper.lambda().eq(SysAddr::getStatus, DictConstant.STATUS_ENABLE);
        wrapper.orderByAsc("ad_cd");
        List<SysAddr> list = baseMapper.selectList(wrapper);
        return list;
    }

    private String getAdCdLike(String adCd) {
        SysAddr baseAddr = getByAdCd(adCd);
        return AddrUtils.getAdCdLike(adCd, baseAddr.getLevel());
    }

    private List<AddrTree> transProperties(List<SysAddr> list, Integer root) {
        List<AddrTree> treeList = new ArrayList<>();
        for (SysAddr baseAddr : list) {
            AddrTree tree = new AddrTree();
            BeanUtils.copyProperties(baseAddr, tree);

            if (root != null) {
                if (baseAddr.getAdCd().substring(0, 1).equals("0")) {
                    tree.setHasChildren(false);
                } else {
                    tree.setHasChildren(true);
                }
            }
            treeList.add(tree);
        }
        return treeList;
    }

    private List<AddrTree> getTree(List<SysAddr> list) {
        // 转换Bean
        List<AddrTree> tree = this.transProperties(list, null);
        // 整合tree
        List<AddrTree> menuTrees = TreeUtils.bulid(tree, TreeUtils.ROOT_NODE.longValue());
        return menuTrees;
    }


}
